package com.imarad.server.nio.handle;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;
import java.util.Arrays;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.imarad.server.common.ClientPacket;

/**
 * @author hhu 【huan.hu@cnambition.com】
 * @version com.imarad.demo, v 0.1 2018/1/30 13:35 hhu Exp $$
 */
public class ServerHandler implements Runnable {
    /**
     * 日志工具
     */
    private static final Logger         LOG              = LoggerFactory
        .getLogger(ServerHandler.class);
    /**
     * 网络套接字
     */
    private SocketChannel               socketChannel;
    /**
     * 启动状态
     */
    private boolean                     isRun;
    /**
     * 主机名
     */
    private String                      ipAddress;
    /**
     * 客户端端口
     */
    private int                         port;
    /**
     * 客户端名称
     */
    private String                      hostName;

    private BlockingQueue<ClientPacket> receiveDataQueue = new LinkedBlockingDeque<>();

    public ServerHandler(SocketChannel socketChannel) {
        this.socketChannel = socketChannel;
        try {
            InetSocketAddress clientAddress = (InetSocketAddress) this.socketChannel
                .getRemoteAddress();
            this.ipAddress = clientAddress.getAddress().getHostAddress();
            this.port = clientAddress.getPort();
            this.hostName = clientAddress.getHostName();
        } catch (IOException e) {
            LOG.error("服务器错误", e);
        }
        isRun = true;
    }

    @Override
    public void run() {
        //缓冲数组
        try {
            while (isRun) {
                //按规定的字节数读取数据
                ClientPacket clientPacket = receiveDataQueue.take();
                if (clientPacket != null) {
                    executeCommand(clientPacket);
                }
            }
        } catch (InterruptedException e) {
            LOG.error("服务器错误", e);
        }
    }

    /**
     * 执行收到的数据包
     * @param clientPacket
     */
    private void executeCommand(ClientPacket clientPacket) {
        try {
            if (clientPacket.getData() != null) {
                String msg = new String(clientPacket.getData(), "UTF-8");
                LOG.info("接收到消息：{}", msg);
            } else {
                LOG.error("接收到的消息有误：{}", clientPacket);
            }
        } catch (UnsupportedEncodingException e) {
            LOG.error("服务器错误", e);
        }
    }

    /**
     * 接收消息
     * @param data
     */
    public void receiveData(byte[] data) throws InterruptedException {
        LOG.trace("接入原始数据：{}", Arrays.toString(data));
        ClientPacket clientPacket;
        if (data != null) {
            // read packet header (17)
            clientPacket = new ClientPacket(data);
            receiveDataQueue.put(clientPacket);
        }
    }

    @Override
    public String toString() {
        return "Client[host=" + hostName + ", ip=" + ipAddress + ", port=" + port + "]";
    }
}